package ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.spring;

import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.impl.AbstractManager;
import ace.cmp.id.generator.api.IdGenerator;
import ace.cmp.spring.data.jdbc.querydsl.core.QuerydslRelationHelper;
import ace.cmp.spring.data.jdbc.querydsl.core.repository.QuerydslJdbcBaseRepository;
import ace.cmp.spring.data.jdbc.querydsl.rsql.core.RsqlQuerydslParser;
import ace.cmp.spring.data.jdbc.querydsl.rsql.core.RsqlQuerydslVisitor;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ResolvableType;

/**
 * use at spring context auto inject.
 *
 * @author caspar
 */
@Slf4j
public abstract class AbstractSpringManager<EntityT, IdT>
    extends AbstractManager<EntityT, IdT>
    implements InitializingBean {

  @Getter(AccessLevel.PROTECTED)
  private final Class<EntityT> entityClass;

  @Getter(value = AccessLevel.PROTECTED)
  private RsqlQuerydslVisitor querydslVisitor;

  @Getter(value = AccessLevel.PROTECTED)
  @Autowired
  private QuerydslJdbcBaseRepository<EntityT, IdT> repository;

  @Getter(value = AccessLevel.PROTECTED)
  @Autowired
  private IdGenerator<IdT> idGenerator;

  @Getter(value = AccessLevel.PROTECTED)
  @Autowired
  private QuerydslRelationHelper querydslRelationHelper;

  @Getter(value = AccessLevel.PROTECTED)
  private RsqlQuerydslParser querydslParser;

  @Getter(AccessLevel.PROTECTED)
  private Class<IdT> idClass;

  public AbstractSpringManager() {
    ResolvableType resolvableType = ResolvableType.forType(this.getClass());
    this.entityClass = (Class<EntityT>) resolvableType.getSuperType().getGeneric(0).getRawClass();
    this.idClass = (Class<IdT>) resolvableType.getSuperType().getGeneric(1).getRawClass();
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    this.querydslVisitor = new RsqlQuerydslVisitor(this.getEntityClass());
  }
}
